using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using Lidgren.Network;

public sealed class AutoServer : AutoPeer
{
	#region public 

	/// <summary>
	/// This name will be sent to all peers that sent discovery request
	/// </summary>
	public string name
	{
		get;
		set;
	}

	/// <summary>
	/// Set up default peer handlers as well as specific handler that will automatically respond to peers requesting discovery
	/// </summary>
	public override void DefaultHandlers()
	{
		base.DefaultHandlers();

		AddMessageHandler(NetIncomingMessageType.DiscoveryRequest, (message, instance) =>
		{
			NetOutgoingMessage response = CreateMessage();
			response.Write(name);
			SendDiscoveryResponse(response, message.SenderEndPoint);
		});
	}

	/// <summary>
	/// Pack and send object to all connections
	/// </summary>
	public void SendObjectToAll(object obj, NetDeliveryMethod method)
	{
		SendToAll(PackObject(obj), method);
	}

	/// <summary>
	/// Pack and send an object to all connection except one
	/// </summary>
	public void SendObjectToAll(object obj, NetConnection except, NetDeliveryMethod method)
	{
		SendToAll(PackObject(obj), except, method, 0);
	}

	#endregion
	#region lidgrenServer

	/// <summary>
	/// AutoServer constructor
	/// </summary>
	public AutoServer(NetPeerConfiguration config)
		: base(config)
	{
		config.AcceptIncomingConnections = true;
		config.EnableMessageType(NetIncomingMessageType.DiscoveryRequest);

		name = "Default Server";
	}

	/// <summary>
	/// Send a message to all connections
	/// </summary>
	/// <param name="msg">The message to send</param>
	/// <param name="method">How to deliver the message</param>
	public void SendToAll(NetOutgoingMessage msg, NetDeliveryMethod method)
	{
		var all = this.Connections;
		if (all.Count <= 0)
			return;

		SendMessage(msg, all, method, 0);
	}

	/// <summary>
	/// Send a message to all connections except one
	/// </summary>
	/// <param name="msg">The message to send</param>
	/// <param name="method">How to deliver the message</param>
	/// <param name="except">Don't send to this particular connection</param>
	/// <param name="sequenceChannel">Which sequence channel to use for the message</param>
	public void SendToAll(NetOutgoingMessage msg, NetConnection except, NetDeliveryMethod method, int sequenceChannel)
	{
		var all = this.Connections;
		if (all.Count <= 0)
			return;

		if (except == null)
		{
			SendMessage(msg, all, method, sequenceChannel);
			return;
		}

		List<NetConnection> recipients = new List<NetConnection>(all.Count - 1);
		foreach (var conn in all)
			if (conn != except)
				recipients.Add(conn);

		if (recipients.Count > 0)
			SendMessage(msg, recipients, method, sequenceChannel);
	}

	/// <summary>
	/// Returns a string that represents this object
	/// </summary>
	public override string ToString()
	{
		return "[AutoServer " + ConnectionsCount + " connections]";
	}

	#endregion
}